<?php

namespace Mini;

class Promise
{
    protected $onFulfilled;
    protected $onRejected;
    protected bool $resolved = false;
    protected bool $rejected = false;
    protected $value;
    protected $reason;

    public function __construct(callable $executor)
    {
        try {
            $executor([$this, 'resolve'], [$this, 'reject']);
        } catch (\Throwable $e) {
            $this->reject($e);
        }
    }

    public function then(callable $onFulfilled): static
    {
        $this->onFulfilled = $onFulfilled;
        if ($this->resolved) {
            ($this->onFulfilled)($this->value);
        }
        return $this;
    }

    public function catch(callable $onRejected): static
    {
        $this->onRejected = $onRejected;
        if ($this->rejected) {
            ($this->onRejected)($this->reason);
        }
        return $this;
    }

    public function resolve($value = null): void
    {
        $this->resolved = true;
        $this->value = $value;
        if ($this->onFulfilled) {
            ($this->onFulfilled)($value);
        }
    }

    public function reject($reason = null): void
    {
        $this->rejected = true;
        $this->reason = $reason;
        if ($this->onRejected) {
            ($this->onRejected)($reason);
        }
    }
}
